const LAST_CONNECTED_DEVICE = 'last_connected_device'
const PrinterJobs = require('@/printer/printerjobs')
const md5 = require("@/utils/md5.js");
const constants = require('@/utils/khyConstants.js')
const request = require('@/utils/request.js')
function inArray(arr, key, val) {
  for (let i = 0; i < arr.length; i++) {
    if (arr[i][key] === val) {
      return i
    }
  }
  return -1
}
// ArrayBuffer转16进度字符串示例
function ab2hex(buffer) {
  const hexArr = Array.prototype.map.call(
    new Uint8Array(buffer),
    function (bit) {
      return ('00' + bit.toString(16)).slice(-2)
    }
  )
  return hexArr.join(',')
}

function str2ab(str) {
  // Convert str to ArrayBuff and write to printer
  let buffer = new ArrayBuffer(str.length)
  let dataView = new DataView(buffer)
  for (let i = 0; i < str.length; i++) {
    dataView.setUint8(i, str.charAt(i).charCodeAt(0))
  }
  return buffer;
}

function buf2hex(buffer) {
  return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
}
//arraybuffer 转字符串
function buf2char(buf) {
  var out = "";
  var u16a = new Uint16Array(buf);
  var single;
  for (var i = 0; i < u16a.length; i++) {
    single = u16a[i].toString(16)
    while (single.length < 4) single = "0".concat(single);
    out += single;
  }
  return out;
}
Page({
  data: {
    orderInfo: {},
    devices: [],
    connected: false,
    chs: [],
    serviceQaPhone:null
  },

  onLoad(options) {
    const lastDevice = wx.getStorageSync(LAST_CONNECTED_DEVICE);
    console.log(lastDevice+"lastDevice")
    if(lastDevice!= ""){
      this.createBLEConnectionWithDeviceId();
    }
    this.getDictData();
    let orderData = getApp().globalData.pageData[constants.page_print]
    let obj = {}
    for (const key in orderData) {
      if (orderData.hasOwnProperty(key)) {
        obj['orderInfo.' + key] = orderData[key]
      }
    }
    obj['lastDevice'] = lastDevice
    this.setData(obj)
  },
  getDictData() {
    let dictString = constants.dict.客服电话
    request.get('/HomeController/getDictData', {dictCode: dictString}).then(res => {
      console.log(res)
      if (res.data.code == constants.resultSuccessCode &&
        res.data.result) {
        let stationData = res.data.result[constants.dict.客服电话] || []
        let serviceQaPhone = []
        stationData.forEach(item => {
          serviceQaPhone = item['itemValue'] || ''
        });
        this.setData({
            serviceQaPhone: serviceQaPhone,
        })
      }
    })
  },
  onUnload() {
    this.closeBluetoothAdapter()
  },
  openBluetoothAdapter() {
    if (!wx.openBluetoothAdapter) {
      wx.showModal({
        title: '提示',
        content: '当前微信版本过低，无法使用该功能，请升级到最新微信版本后重试。'
      })
      return
    }
    wx.openBluetoothAdapter({
      success: (res) => {
        console.log('openBluetoothAdapter success', res)
        this.startBluetoothDevicesDiscovery()
      },
      fail: (res) => {
        console.log('openBluetoothAdapter fail', res)
        if (res.errCode === 10001) {
          wx.showModal({
            title: '错误',
            content: '未找到蓝牙设备, 请打开蓝牙后重试。',
            showCancel: false
          })
          wx.onBluetoothAdapterStateChange((res) => {
            console.log('onBluetoothAdapterStateChange', res)
            if (res.available) {
              // 取消监听，否则stopBluetoothDevicesDiscovery后仍会继续触发onBluetoothAdapterStateChange，
              // 导致再次调用startBluetoothDevicesDiscovery
              wx.onBluetoothAdapterStateChange(() => {});
              this.startBluetoothDevicesDiscovery()
            }
          })
        }
      }
    })
    wx.onBLEConnectionStateChange((res) => {
      // 该方法回调中可以用于处理连接意外断开等异常情况
      console.log('onBLEConnectionStateChange', `device ${res.deviceId} state has changed, connected: ${res.connected}`)
      this.setData({
        connected: res.connected
      })
      if (!res.connected) {
        wx.showModal({
          title: '',
          content: '蓝牙连接已断开',
          showCancel: false
        })
      }
    });
  },
  getBluetoothAdapterState() {
    wx.getBluetoothAdapterState({
      success: (res) => {
        console.log('getBluetoothAdapterState', res)
        if (res.discovering) {
          this.onBluetoothDeviceFound()
        } else if (res.available) {
          this.startBluetoothDevicesDiscovery()
        }
      }
    })
  },
  startBluetoothDevicesDiscovery() {
    if (this._discoveryStarted) {
      return
    }
    this._discoveryStarted = true
    wx.startBluetoothDevicesDiscovery({
      success: (res) => {
        console.log('startBluetoothDevicesDiscovery success', res)
        this.onBluetoothDeviceFound()
      },
      fail: (res) => {
        console.log('startBluetoothDevicesDiscovery fail', res)
      }
    })
  },
  stopBluetoothDevicesDiscovery() {
    wx.stopBluetoothDevicesDiscovery({
      complete: () => {
        console.log('stopBluetoothDevicesDiscovery')
        this._discoveryStarted = false
      }
    })
  },
  onBluetoothDeviceFound() {
    wx.onBluetoothDeviceFound((res) => {
      res.devices.forEach(device => {
        if (!device.name && !device.localName) {
          return
        }
        const foundDevices = this.data.devices
        const idx = inArray(foundDevices, 'deviceId', device.deviceId)
        const data = {}
        if (idx === -1) {
          data[`devices[${foundDevices.length}]`] = device
        } else {
          data[`devices[${idx}]`] = device
        }
        this.setData(data)
      })
    })
  },
  createBLEConnection(e) {
    const ds = e.currentTarget.dataset
    const deviceId = ds.deviceId
    const name = ds.name
    this._createBLEConnection(deviceId, name)
  },
  _createBLEConnection(deviceId, name) {
    wx.showLoading()
    wx.createBLEConnection({
      deviceId,
      success: () => {
        console.log('createBLEConnection success');
        this.setData({
          connected: true,
          name,
          deviceId,
        })
        this.getBLEDeviceServices(deviceId)
        wx.setStorageSync(LAST_CONNECTED_DEVICE,name + ':' + deviceId);
        // wx.setStorage({
        //   key: LAST_CONNECTED_DEVICE,
        //   data: name + ':' + deviceId
        // })
      },
      complete() {
        wx.hideLoading()
      },
      fail: (res) => {
        console.log('createBLEConnection fail', res)
      }
    })
    this.stopBluetoothDevicesDiscovery()
  },
  closeBLEConnection() {
    wx.closeBLEConnection({
      deviceId: this.data.deviceId
    })
    this.setData({
      connected: false,
      chs: [],
      canWrite: false,
      canRead: false
    })
  },
  getBLEDeviceServices(deviceId) {
    wx.getBLEDeviceServices({
      deviceId,
      success: (res) => {
        console.log('getBLEDeviceServices', res)
        for (let i = 0; i < res.services.length; i++) {
          if (res.services[i].isPrimary) {
            this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid)
            return
          }
        }
      }
    })
  },
  getBLEDeviceCharacteristics(deviceId, serviceId) {
    wx.getBLEDeviceCharacteristics({
      deviceId,
      serviceId,
      success: (res) => {
        console.log('getBLEDeviceCharacteristics success', res.characteristics)
        // 这里会存在特征值是支持write，写入成功但是没有任何反应的情况
        // 只能一个个去试
        for (let i = 0; i < res.characteristics.length; i++) {
          const item = res.characteristics[i]
          if (item.properties.write) {
            this.setData({
              canWrite: true
            })
            this._deviceId = deviceId
            this._serviceId = serviceId
            this._characteristicId = item.uuid
            break;
          }
        }
        for (let j = 0; j < res.characteristics.length; j++) {
          const item = res.characteristics[j]
          if (item.properties.notify) {
            this.setData({
              canRead: true
            })
            this._readId = item.uuid
            break;
          }
        }
      },
      fail(res) {
        console.error('getBLEDeviceCharacteristics', res)
      }
    })
  },
  writeBLECharacteristicValue() {
    let printerJobs = new PrinterJobs();
    /**
     * ESC/POS指令打印
     *  首先需自己定义位置坐标设计样式
     * */
     let orderInfo=this.data.orderInfo
     console.log(orderInfo+orderInfo)
     let packageNo= orderInfo.packageNo
     let consigneePhone= orderInfo.consigneePhone.substring(0,3)+"****"+orderInfo.consigneePhone.substring(7,orderInfo.consigneePhone.length)
     let senderPhone= orderInfo.senderPhone.substring(0,3)+"****"+orderInfo.senderPhone.substring(7,orderInfo.senderPhone.length)
     printerJobs
      .label_set_page(576, 980)
      .setPrintOk(1)
      // 第一个
       .drawbox(2, 0, 0, 150, 100)
       .drawText(100, 20, "寄", 2, 4, 3, 1, false, false)
       // 第二个
       .drawbox(2, 0, 100, 150, 500)
       .drawText(140, 120, orderInfo.senderName+":"+senderPhone , 2, 2, 3, 1, false, false)
       .drawText(75, 120,orderInfo.startStationName, 2, 2, 3, 1, false, false)
      // 第三个
      .drawbox(2, 0, 500, 150, 900)
      .drawText(140, 520, orderInfo.payMode=="1"?"现付":"到付", 2, 2, 3, 1, false, false)
      .drawText(75, 520, "客服电话:"+this.data.serviceQaPhone, 2, 2, 3, 1, false, false)
       // 第四个
      .drawbox(2, 150, 0, 300, 100)
      .drawText(250, 20, "收", 2, 4, 3, 1, false, false)
      // 第五个
      .drawbox(2, 150, 100, 300, 500)
      .drawText(280, 120,orderInfo.consigneeName+":"+consigneePhone , 2, 2, 3, 1, false, false)
      .drawText(205, 120,orderInfo.endStationName , 2, 2, 3, 1, false, false)
      // 第六个
      .drawbox(2, 150, 500, 300, 900)
      .drawText(280, 520, "物品:"+orderInfo.goodsName, 2, 2, 3, 1, false, false)
     // 第七个
     .drawbox(2, 300, 0, 480, 900)
     .drawBarCode(1,5,2,1,100,370,600,packageNo)
     //.drawQrCode(320,800,packageNo,1,180,10)
     .drawText(360, 120,packageNo, 2, 1, 3, 1, false, false)
     //日期
     .drawText(540, 120, orderInfo.orderTime, 2, 2, 3, 1, false, false)
      /// 第二种模板
      // .drawText(0, 0, "包头客货邮", 2, 0, 1, false, false)
      // .drawText(400, 0, "快递", 2, 0, 1, false, false)
      // .drawText(0, 40, "2023/12/04 10:00:00", 2, 0, 1, false, false)
      // .drawText(400, 40, "包裹", 2, 0, 1, false, false)
      // // 表格
      // .drawbox(2, 0, 100, 500, 300)
      // // 条形码
      // .drawBarCode(350, 100, "12345678912345", 0, 0, 1, 100)
      // .drawText(50, 230, "12345678912345", 6, 0, 1, false, false)
      // //第二行
      // .drawbox(2, 0, 300, 100, 400)
      // .drawText(20, 320, "收", 2, 0, 1, false, false)
      // .drawbox(2, 100, 300, 500, 400)
      // .drawText(100, 310, "张先生152****5612", 2, 0, 1, false, false)
      // .drawText(100, 350, "内蒙古包头市石拐区青山村", 2, 0, 1, false, false)

      // //第三行
      // .drawbox(2, 0, 400, 100, 500)
      // .drawText(20, 420, "寄", 2, 0, 1, false, false)
      // .drawbox(2, 100, 400, 500, 500)
      // .drawText(100, 410, "李先生152****5612", 2, 0, 1, false, false)
      // .drawText(100, 450, "内蒙古包头市南绕城", 2, 0, 1, false, false)
      // //第四行
      // .drawbox(2, 0, 500, 500, 580)
      // .drawText(50, 520, "订单号:12345678912345", 2, 0, 1, false, false)
      // //物品
      // .drawText(50, 600, "物品:", 2, 0, 1, false, false)
      // .drawText(200, 600, "日用品", 2, 0, 1, false, false)
      // .drawText(50, 650, "寄付现结", 2, 0, 1, false, false)
      // // 客服
      // .drawText(50, 700, "客服电话:152****1234", 2, 0, 1, false, false)
      .label_print(0, 1);
    let buffer = printerJobs.buffer();
    console.log('ArrayBuffer', 'length: ' + buffer.byteLength, ' hex: ' + ab2hex(buffer));
    // 1.并行调用多次会存在写失败的可能性
    // 2.建议每次写入不超过20字节
    // 分包处理，延时调用
    const maxChunk = 20;
    const delay = 20;
    for (let i = 0, j = 0, length = buffer.byteLength; i < length; i += maxChunk, j++) {
      let subPackage = buffer.slice(i, i + maxChunk <= length ? (i + maxChunk) : length);
      setTimeout(this._writeBLECharacteristicValue, j * delay, subPackage);
    }
  },
  _writeBLECharacteristicValue(buffer) {
    wx.writeBLECharacteristicValue({
      deviceId: this._deviceId,
      serviceId: this._serviceId,
      characteristicId: this._characteristicId,
      value: buffer,
      success(res) {
        console.log('writeBLECharacteristicValue success', res)
      },
      fail(res) {
        console.log('writeBLECharacteristicValue fail', res)
      }
    })
  },
  receiveDate() {
    //监听通知
    wx.onBLECharacteristicValueChange(function (res) {
        var app = getApp()
        // callback
        console.log('value change', res)
        if (res.value != null) {
          const hex = buf2hex(res.value);
          console.log('返回的数据：', hex);
          // if(hex==12){
          //   wx.showModal({
          //     title: '打印机状态',
          //     content: '正常。',
          //     showCancel: false
          //   })
          // }else if(hex==32){
          //   wx.showModal({
          //     title: '打印机状态',
          //     content: '缺纸。',
          //     showCancel: false
          //   })
          // }else{
          //   wx.showModal({
          //     title: '打印机状态',
          //     content: '其他错误。',
          //     showCancel: false
          //   })
          // }
          if (hex == "4f4b") {
            app.globalData.printNum = app.globalData.printNum + 1;
            console.log('打印次数', app.globalData.printNum);
          }
        }
      }),
      wx.notifyBLECharacteristicValueChanged({
        deviceId: this._deviceId,
        serviceId: this._serviceId,
        characteristicId: this._readId,
        state: true,
        success: function (res) {
          // success
          console.log('notify', res)
        },
        fail: function (res) {
          console.log('失败', res)
        }
      })
  },
  closeBluetoothAdapter() {
    wx.closeBluetoothAdapter()
    this._discoveryStarted = false
  },
  
  createBLEConnectionWithDeviceId(e) {
    // 小程序在之前已有搜索过某个蓝牙设备，并成功建立连接，可直接传入之前搜索获取的 deviceId 直接尝试连接该设备
    const device = this.data.lastDevice
    if (!device) {
      return
    }
    const index = device.indexOf(':');
    const name = device.substring(0, index);
    const deviceId = device.substring(index + 1, device.length);
    console.log('createBLEConnectionWithDeviceId', name + ':' + deviceId)
    wx.openBluetoothAdapter({
      success: (res) => {
        console.log('openBluetoothAdapter success', res)
        this._createBLEConnection(deviceId, name)
      },
      fail: (res) => {
        console.log('openBluetoothAdapter fail', res)
        if (res.errCode === 10001) {
          wx.showModal({
            title: '错误',
            content: '未找到蓝牙设备, 请打开蓝牙后重试。',
            showCancel: false
          })
          wx.onBluetoothAdapterStateChange((res) => {
            console.log('onBluetoothAdapterStateChange', res)
            if (res.available) {
              // 取消监听
              wx.onBluetoothAdapterStateChange(() => {});
              this._createBLEConnection(deviceId, name)
            }
          })
        }
      }
    })
  },
})